//
// Created by 32827 on 2024/7/3.
//

#ifndef STM32F407RTOS_YZF_ADC_H
#define STM32F407RTOS_YZF_ADC_H
#include "yzf.h"

/**
 * 开启APB2时钟
 * */
YZF_RESULT yzf_adc_clock_open(YZF_ADC_POINTER adc);
YZF_RESULT yzf_adc_cr_reset(YZF_ADC_POINTER adc);
YZF_RESULT yzf_adc_dma_enable(YZF_ADC_POINTER adc,YZF_BOOL isEnable);
/**
 * DMA 禁止选择（对于单一 ADC 模式） (DMA disable selection (for single ADC mode))
 * @note
 * <br>0：最后一次传输后不发出新的 DMA 请求（在 DMA 控制器中进行配置）
 * <br>1：只要发生数据转换且 DMA = 1，便会发出 DAM 请求
 * */
YZF_RESULT yzf_adc_dma_disable_selection(YZF_ADC_POINTER adc,YZF_BOOL isEnable);
/**
 * 溢出 (Overrun)
 * @SetByHard Set 1
 * @ClearBySoft Set 0
 * */
YZF_BOOL yzf_adc_flag_OVR(YZF_ADC_POINTER adc,YZF_BOOL isClear);

/**
 * 规则通道转换结束 (Regular channel end of conversion)
 * @SetByHard Set 1
 * @ClearBySoft Set 0
 * @ClearByRead ADC_DR
 * */
YZF_BOOL yzf_adc_flag_EOC(YZF_ADC_POINTER adc,YZF_BOOL isClear);

/**
 * 注入通道转换结束 (Injected channel end of conversion)
 * @SetByHard Set 1
 * @ClearBySoft Set 0
 * */
YZF_BOOL yzf_adc_flag_JEOC(YZF_ADC_POINTER adc,YZF_BOOL isClear);

/**
 * 模拟看门狗标志 (Analog watchdog flag)
 * @SetByHard Set 1
 * @ClearBySoft Set 0
 * */
YZF_BOOL yzf_adc_flag_AWD(YZF_ADC_POINTER adc,YZF_BOOL isClear);

/**
 * 注入通道开始标志 (Injected channel start flag)
 * @SetByHard Set 1
 * @ClearBySoft Set 0
 * */
YZF_BOOL yzf_adc_flag_JSTRT(YZF_ADC_POINTER adc,YZF_BOOL isClear);

/**
 * 规则通道开始标志 (Regular channel start flag)
 * @SetByHard Set 1
 * @ClearBySoft Set 0
 * */
YZF_BOOL yzf_adc_flag_STRT(YZF_ADC_POINTER adc,YZF_BOOL isClear);

/**
 * 溢出中断使能 (Overrun interrupt enable)
 * */
YZF_RESULT yzf_adc_interrupt_OVR_enable(YZF_ADC_POINTER adc);

/**
 * 溢出中断关闭 (Overrun interrupt disable)
 * */
YZF_RESULT yzf_adc_interrupt_OVR_disable(YZF_ADC_POINTER adc);

typedef enum YZF_ADC_RESOLUTION_ENUM{
    YZF_ADC_RESOLUTION_12BIT = 0,
    YZF_ADC_RESOLUTION_10BIT = 1,
    YZF_ADC_RESOLUTION_8BIT = 2,
    YZF_ADC_RESOLUTION_6BIT = 3,
} YZF_ADC_RESOLUTION;
/**
 * 分辨率 (Resolution)
 * @param resolution YZF_ADC_RESOLUTION_XBIT
 * */
YZF_RESULT yzf_adc_resolution_set(YZF_ADC_POINTER adc,YZF_ADC_RESOLUTION resolution);

/**
 * 规则通道上的模拟看门狗使能 (Analog watchdog enable on regular channels)
 * */
YZF_RESULT yzf_adc_AWD_enable(YZF_ADC_POINTER adc);

/**
 * 规则通道上的模拟看门狗关闭 (Analog watchdog disable on regular channels)
 * */
YZF_RESULT yzf_adc_AWD_disable(YZF_ADC_POINTER adc);

/**
 * 注入通道上的模拟看门狗使能 (Analog watchdog enable on injected channels)
 * */
YZF_RESULT yzf_adc_JAWD_enable(YZF_ADC_POINTER adc);

/**
 * 注入通道上的模拟看门狗关闭 (Analog watchdog disable on injected channels)
 * */
YZF_RESULT yzf_adc_JAWD_disable(YZF_ADC_POINTER adc);

/**
 * 注入组自动转换使能 (Automatic injected group conversion enable)
 * */
YZF_RESULT  yzf_adc_JAUTO_enable(YZF_ADC_POINTER adc);

/**
 * 注入组自动转换关闭 (Automatic injected group conversion disable)
 * */
YZF_RESULT  yzf_adc_JAUTO_disable(YZF_ADC_POINTER adc);

/**
 * 注入通道的中断使能 (Interrupt enable for injected channels)
 * */
YZF_RESULT yzf_adc_interrupt_JEOC_enable(YZF_ADC_POINTER adc);

/**
 * 注入通道的中断关闭 (Interrupt disable for injected channels)
 * */
YZF_RESULT yzf_adc_interrupt_JEOC_disable(YZF_ADC_POINTER adc);

/**
 * 模拟看门狗中断使能 (Analog watchdog interrupt enable)
 * */
YZF_RESULT yzf_adc_interrupt_AWD_enable(YZF_ADC_POINTER adc);

/**
 * 模拟看门狗中断关闭 (Analog watchdog interrupt disable)
 * */
YZF_RESULT yzf_adc_interrupt_AWD_disable(YZF_ADC_POINTER adc);

/**
 * EOC 中断使能 (Interrupt enable for EOC)
 * */
YZF_RESULT yzf_adc_interrupt_EOC_enable(YZF_ADC_POINTER adc);

/**
 * EOC 中断使能 (Interrupt disable for EOC)
 * */
YZF_RESULT yzf_adc_interrupt_EOC_disable(YZF_ADC_POINTER adc);

/**
 * 模拟看门狗通道选择位 (Analog watchdog channel select bits)
 * @param channel_select chX x为编号
 * */
YZF_RESULT yzf_adc_watchdog_channel_set(YZF_ADC_POINTER adc,uint8_t channel_select);

/**
 * 开始转换规则通道 (Start conversion of regular channels)
 * @SetBySoft Set 1
 * @ClearByHard Set 0
 * */
YZF_RESULT yzf_adc_SWSTART(YZF_ADC_POINTER adc);

/**
 *  规则通道的外部触发使能 (External trigger enable for regular channels)
 * @param ext <br>
 *  0b00：禁止触发检测 <br>
 *  0b01：上升沿上的触发检测 <br>
 *  0b10：下降沿上的触发检测 <br>
 *  0b11：上升沿和下降沿上的触发检测 <br>
 *  @SetBySoft Set 1
 *  @ClearBySoft Set 0
 * */
YZF_RESULT yzf_adc_EXTEN(YZF_ADC_POINTER adc,uint8_t ext);

/**
 * 为规则组选择外部事件 (External event select for regular group)
 * @param extsel
 * <br>0000：定时器 1 CC1 事件
 * <br>0001：定时器 1 CC2 事件
 * <br>0010：定时器 1 CC3 事件
 * <br>0011：定时器 2 CC2 事件
 * <br>0100：定时器 2 CC3 事件
 * <br>0101：定时器 2 CC4 事件
 * <br>0110：定时器 2 TRGO 事件
 * <br>0111：定时器 3 CC1 事件
 * <br>1000：定时器 3 TRGO 事件
 * <br>1001：定时器 4 CC4 事件
 * <br>1010：定时器 5 CC1 事件
 * <br>1011：定时器 5 CC2 事件
 * <br>1100：定时器 5 CC3 事件
 * <br>1101：定时器 8 CC1 事件
 * <br>1110：定时器 8 TRGO 事件
 * <br>1111：EXTI 线 11
 * */
YZF_RESULT yzf_adc_EXTSEL(YZF_ADC_POINTER adc,uint8_t extsel);

/**
 * 开始转换注入通道 (Start conversion of injected channels)
 * @SetBySoft Set 1
 * @ClearByHard Set 0
 * */
YZF_RESULT yzf_adc_JSWSTART(YZF_ADC_POINTER adc);

/**
 * 注入通道的外部触发使能 (External trigger enable for injected channels)
 * @param ext <br>
 *  0b00：禁止触发检测 <br>
 *  0b01：上升沿上的触发检测 <br>
 *  0b10：下降沿上的触发检测 <br>
 *  0b11：上升沿和下降沿上的触发检测 <br>
 * */
YZF_RESULT  yzf_adc_JEXTEN(YZF_ADC_POINTER adc,uint8_t ext);

/**
 * 为注入组选择外部事件 (External event select for injected group)
 * @param extsel <br>
 * <br>0000：定时器 1 CC4 事件
 * <br>0001：定时器 1 TRGO 事件
 * <br>0010：定时器 2 CC1 事件
 * <br>0011：定时器 2 TRGO 事件
 * <br>0100：定时器 3 CC2 事件
 * <br>0101：定时器 3 CC4 事件
 * <br>0110：定时器 4 CC1 事件
 * <br>0111：定时器 4 CC2 事件
 * <br>1000：定时器 4 CC3 事件
 * <br>1001：定时器 4 TRGO 事件
 * <br>1010：定时器 5 CC4 事件
 * <br>1011：定时器 5 TRGO 事件
 * <br>1100：定时器 8 CC2 事件
 * <br>1101：定时器 8 CC3 事件
 * <br>1110：定时器 8 CC4 事件
 * <br>1111：EXTI 线 15
 * */
YZF_RESULT yzf_adc_JEXTSEL(YZF_ADC_POINTER adc,uint8_t extsel);

/**
 * 数据对齐 (Data alignment)
 * */
YZF_RESULT  yzf_adc_ALIGN(YZF_ADC_POINTER adc,YZF_BOOL isLeft);

/**
 * 结束转换选择 (End of conversion selection)
 * */
YZF_RESULT  yzf_adc_EOCS(YZF_ADC_POINTER adc,YZF_BOOL isEOCS);

/**
 * 连续转换 (Continuous conversion)
 * */
YZF_RESULT  yzf_adc_CONT(YZF_ADC_POINTER adc,YZF_BOOL isContinue);

/**
 * A/D 转换器开启 / 关闭 (A/D Converter ON / OFF)
 * */
YZF_RESULT  yzf_adc(YZF_ADC_POINTER adc,YZF_BOOL isOn);

/**
 * ADC sample time register
 * @param smpr <br>
 * <br>000：3 个周期
 * <br>001：15 个周期
 * <br>010：28 个周期
 * <br>011：56 个周期
 * <br>100：84 个周期
 * <br>101：112 个周期
 * <br>110：144 个周期
 * <br>111：480 个周期
 * */
YZF_RESULT yzf_adc_SMPR(YZF_ADC_POINTER adc,uint8_t ch,uint8_t smpr);

/**
 * ADC 注入通道数据偏移寄存器 X (ADC_JOFRx)
 * <br>通过软件写入这些位可定义在转换注入通道时从原始转换数据中减去的偏移量。可从ADC_JDRx 寄存器中读取转换结果。
 * @param ch 1-4
 * @param offset 12bits
 * */
YZF_RESULT yzf_adc_JOFR_set(YZF_ADC_POINTER adc,uint8_t ch,uint16_t offset);

/**
 * ADC 看门狗高阈值寄存器 (ADC_HTR)
 * @param htr 12bits
 * @note 转换结果高于此值时，将触发看门狗中断
 * */
YZF_RESULT yzf_adc_HTR_set(YZF_ADC_POINTER adc,uint16_t htr);

/**
 * ADC 看门狗低阈值寄存器 (ADC_LTR)
 *  @param ltr 12bits
 *  @note 转换结果低于此值时，将触发看门狗中断
 * */
YZF_RESULT yzf_adc_LTR_set(YZF_ADC_POINTER adc,uint16_t ltr);

/**
 * ADC 注入数据寄存器
 * @param jdr 1-4
 * */
uint16_t yzf_adc_JDR_get(YZF_ADC_POINTER adc,uint8_t jdr);

/**
 * ADC 规则数据寄存器
 * */
uint16_t yzf_adc_DR_get(YZF_ADC_POINTER adc);

/**
 * ADC_SQR ADC 规则序列寄存器
 * <br>0000：1 次转换
 * <br>0001：2 次转换
 * <br>...
 * <br>1111：16 次转换
 * @param counts 写入次数即可，会自动 -1
 * */
YZF_RESULT yzf_adc_SQR_Counts_set(YZF_ADC_POINTER adc,uint8_t counts);

/**
 * 通道转换
 *  @param ch 通道 0-18
 *  @param sqr 规则序列编号 1-16
 * */
YZF_RESULT yzf_adc_SQR_set(YZF_ADC_POINTER adc,uint8_t ch,uint8_t sqr);

/**
 * JSQR ADC 注入序列寄存器
 * <br>00：1 次转换
 * <br>01：2 次转换
 * <br>10：3 次转换
 * <br>11：4 次转换
 * */
YZF_RESULT  yzf_adc_JSQR_Counts_set(YZF_ADC_POINTER adc,uint8_t counts);

/**
 * ADC 注入序列寄存器
 * @param ch 通道 0-18
 * @param jqr 注入序列编号 1-4
 * @note
 * <br>当 JL[1:0] = 3（定序器中有 4 次注入转换）时，ADC 将按以下顺序转换通道：JSQ1[4:0]、
 * <br>JSQ2[4:0]、JSQ3[4:0] 和 JSQ4[4:0]。
 * <br>当 JL = 2（定序器中有 3 次注入转换）时，ADC 将按以下顺序转换通道：JSQ2[4:0]、
 * <br>JSQ3[4:0] 和 JSQ4[4:0]。
 * <br>当 JL = 1（定序器中有 2 次注入转换）时，ADC 转换通道的顺序为：先是 JSQ3[4:0]，而后
 * <br>是 JSQ4[4:0]。
 * <br>当 JL = 0（定序器中有 1 次注入转换）时，ADC 将仅转换 JSQ4[4:0] 通道
 * */
YZF_RESULT yzf_adc_JSQR_set(YZF_ADC_POINTER adc,uint8_t ch,uint8_t jsq);

/**
 * ADC 扫描模式
 * */
YZF_RESULT yzf_adc_SCAN(YZF_ADC_POINTER adc,YZF_BOOL isScan);
#endif //STM32F407RTOS_`YZF_ADC_H